﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Security.Cryptography;
//using BusinessObjects;
using Entities;

namespace RMSoftware.Models
{
    public class UserRepository
    {
        #region Поля и константы

        private const int CREATE_SALT_BUFFER_LENGTH = 32;
        private const string PASSWORD_FORMAT = "md5";

        private RMDatabaseEntities _db;

        #endregion

        public UserRepository()
        {
            _db = new RMDatabaseEntities();
        }

        public MembershipUser CreateUser(string firstName,
            string lastName,
            string position,
            string username,
            string password,
            string email)
        {
            Person person = new Person
            {
                PersonId = Guid.NewGuid(),
                RoleId = TeamMemberRoleId,
                FirstName = firstName,
                LastName = lastName,
                Position = position,
                Username = username,
                PasswordSalt = CreateSalt(),
                Email = email
            };
            person.Password = CreatePasswordHash(password, person.PasswordSalt);

            _db.Persons.AddObject(person);
            _db.SaveChanges();

            return GetUser(username);
        }

        public string GetUserNameByEmail(string email)
        {
            Person person = _db.Persons.FirstOrDefault(p => p.Email == email);

            return (person != null) ? person.Username : string.Empty;
        }

        public MembershipUser GetUser(string username)
        {
            Person person = _db.Persons.FirstOrDefault(p => p.Username == username);

            if (person != null)
            {
                string _username = person.Username;
                Guid _providerUserKey = person.PersonId;
                string _email = person.Email;
                string _passwordQuestion = string.Empty;
                string _comment = string.Empty;
                bool _isApproved = false;
                bool _isLockedOut = false;
                DateTime _creationDate = DateTime.Now;
                DateTime _lastLoginDate = DateTime.Now;
                DateTime _lastActivityDate = DateTime.Now;
                DateTime _lastPasswordChangedDate = DateTime.Now;
                DateTime _lastLockedOutDate = DateTime.Now;

                MembershipUser user = new MembershipUser("CustomMembershipProvider",
                                                          _username,
                                                          _providerUserKey,
                                                          _email,
                                                          _passwordQuestion,
                                                          _comment,
                                                          _isApproved,
                                                          _isLockedOut,
                                                          _creationDate,
                                                          _lastLoginDate,
                                                          _lastActivityDate,
                                                          _lastPasswordChangedDate,
                                                          _lastLockedOutDate);

                return user;
            }

            return null;
        }

        public string GetUserRole(string username)
        {
            Person person = _db.Persons.FirstOrDefault(p => p.Username == username);

            return person.Role.Title;
        }

        public bool ValidateUser(string username, string password)
        {
            Person person = _db.Persons.FirstOrDefault(p => p.Username == username);

            return person != null && person.Password == CreatePasswordHash(password, person.PasswordSalt);
        }

        #region Вспомогательные свойства и функции

        private Guid TeamMemberRoleId
        {
            get
            {
                return _db.Roles.FirstOrDefault(r => r.Title == "TeamMember").RoleId;
            }
        }

        private Guid ProjectManagerRoleId
        {
            get
            {
                return _db.Roles.FirstOrDefault(r => r.Title == "ProjectManager").RoleId;
            }
        }

        private static string CreateSalt()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[CREATE_SALT_BUFFER_LENGTH];
            rng.GetBytes(buff);

            return Convert.ToBase64String(buff);
        }

        private static string CreatePasswordHash(string pwd, string salt)
        {
            string saltAndPwd = String.Concat(pwd, salt);
            string hashedPwd =
                    FormsAuthentication.HashPasswordForStoringInConfigFile(
                    saltAndPwd, PASSWORD_FORMAT);
            return hashedPwd;
        }

        #endregion
    }
}